﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;

namespace Archiver
{
    class FunctionTableValues
    {
        public struct TableValues
        {
            public int X;
            public int Y;
            public List<bool> Value;
        }

        private static List<TableValues> LoadedValues;

        private static List<TableValues>[] llv;

        private static BinTree Bintr; 


        /// <summary>
        /// Инициализирует таблицу значений функции x^y
        /// </summary>
        public static void InitValuesTables()
        {
            
            
            llv= new List<TableValues>[257];
            for (var i = 0; i <= 256;i++ )
            {
                llv[i] = new List<TableValues>();
            }
            
            LoadedValues = new List<TableValues>();
            var f = new StreamReader("initValuesTable.txt",Encoding.UTF8);

            while (!f.EndOfStream)
            {
                var s = f.ReadLine();
                if (s == null)
                   continue;
                var arr = s.Split('|');
                    
                var t = new TableValues {Value =Binary.ConvertStrToBitArray(arr[0]), X = int.Parse(arr[1]), Y = int.Parse(arr[2])};
                llv[t.Value.Count].Add(t);
                LoadedValues.Add(t);
            }
            f.Close();

            Bintr = new BinTree(LoadedValues);
            
            #region Инициализация данных в файл

/*
            for (var x=0;x<=255; x++)
                for (var y=0;y<=255; y++)
                {
                    var bigX = new BigInteger(x);
                    var resultBin = Binary.ConvertIntToBin(BigInteger.Pow(x,y));
                    if (resultBin.Length>256 || resultBin.Length<32 || bigX.IsPowerOfTwo)
                        continue;
                    f.WriteLine(string.Format("{0}||{1}|{2}",resultBin,x,y));
                }
            f.Close();*/

            #endregion
        }

        /// <summary>
        /// Существуют ли параметры XY при известном значении
        /// </summary>
        /// <param name="value">Значение функции</param>
        /// <param name="x">Параметр Х</param>
        /// <param name="y">Параметр У</param>
        /// <returns>true - если параметры существуют</returns>
        public static bool IsValuePresent(List<bool> value, out int x, out int y)
        {
            BinTree.XY  r;
            if (Bintr.FindXYByValue(value, out r))
            {
                x = r.x;
                y = r.y;
                return true;
            }
            x = 0;
            y = 0;
            return false;
        }
        
        public static List<bool> GetValueByXY(byte x,byte y)
        {
            return (from a in LoadedValues where a.X == x && a.Y == y select a.Value).FirstOrDefault();
        }



        /*
        /// <summary>
        /// Существует ли значение при заданных параметрах Х и У
        /// </summary>
        /// <param name="x">параметр Х</param>
        /// <param name="y">Параметр Y</param>
        /// <param name="value">Значение функции</param>
        /// <returns>true - если параметр существует</returns>
       public bool GetValueByXY(int x, int y, out string value)
        {
            foreach (var t in LoadedValues)
            {
                var t1 = t; 
                if (t1.X==x && t1.Y==y)
                {
                    value = t1.Value;
                    return true; 
                }
            }
            value = "";
            return false;
        }
         * */
    }
}
